/**
在 React 中，高阶组件（Higher-Order Component，简称 HOC）是一种用于复用组件逻辑的设计模式。高阶组件是一个函数，它接受一个组件并返回一个新的组件，从而增强原组件的功能
  1. 基本概念
  - 高阶组件是一个函数，接受一个组件作为参数，并返回一个新的组件。它可以用于添加额外的功能或逻辑，例如数据获取、状态管理、权限控制等。
  示例：
  jsx
  const withLogging = (WrappedComponent) => {
    return class extends React.Component {
      componentDidMount() {
        console.log('Component mounted:', WrappedComponent.name);
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }
    };
  };

  // 使用高阶组件
  const MyComponent = (props) => <div>{props.message}</div>;
  const EnhancedComponent = withLogging(MyComponent);
  2. 高阶组件的用途
  - 代码复用：高阶组件可以将共享的逻辑提取到一个函数中，从而在多个组件之间复用。
  - 逻辑抽象：可以将一些复杂的逻辑抽象为高阶组件，使得组件更加简洁。
  - 条件渲染：可以根据条件动态渲染不同的组件或增强功能。

  3. 注意事项
  - 不修改原组件：高阶组件应该不直接修改传入的组件，而是返回一个新的组件。
  - 传递 Props：高阶组件应该将 props 传递给被包装的组件，以确保其正常工作。
  - 命名冲突：在使用高阶组件时，注意避免 props 的命名冲突，可以使用  `...props`  语法将所有 props 传递下去。

  4. 使用场景
  - 数据获取：通过高阶组件封装数据获取逻辑，比如从 API 获取数据。
  - 权限控制：根据用户权限动态渲染组件。
  - 性能优化：通过缓存或其他方式优化组件性能。

  5. 总结
  高阶组件是 React 中一种强大的设计模式，可以有效地复用组件逻辑，增强组件的功能。通过将共享逻辑抽象为高阶组件，开发者可以提高代码的可维护性和可读性。在使用高阶组件时，需要注意不修改原组件、合理传递 props 以及避免命名冲突等问题。
 */
  import React, { Component } from 'react'
  import enhancedProps from './hoc/enhanced_props'
  import ThemeContext from './context/theme_context'

  import Product from './pages/Product'
  import Cart from './pages/Cart'
  import Detail from './pages/Detail'

  // 定义一个高阶组件
  function hoc(Cpn) {
    // 1. 定义一个类组件
    return class extends Component {
      render() {
        return <Cpn {...this.props} name="higher-order component"/>
      }
    }
  
    // 2. 定义函数组件
    // return function NewCpn2(props) {}
  }
  
  class ChildCpns extends Component {
    render() {
      return <div>hello childCpns</div>
    }
  }
  const EnhancedChildCpns = hoc(ChildCpns)

  const Home = enhancedProps(function(props) {
    return <div>Home: {props.name}-{props.level}-{props.banners}</div>
  })
  
  export default class App extends Component {

    login() {
      console.log("login")
      localStorage.setItem("token", "token123456")
      this.forceUpdate() // 强制更新
    }
    
    render() {
      return (
        <div>
          <h3>01_高阶组件的定义和作用</h3>
          <EnhancedChildCpns />

          <h3>02_高阶组件应用-props增强</h3>
          <Home banners={["banner1", "banner2"]}/>

          <h3>03_高阶组件应用-Context共享</h3>
          <ThemeContext.Provider value={{color: "red", size: 20}}>
            <Product />
          </ThemeContext.Provider>

          <h3>04_高阶组件应用-登录鉴权</h3>
          <button onClick={e => this.login()}>登录</button>
          <Cart />

          <h3>05_高阶组件应用-生命周期</h3>
          <Detail />
          
        </div>
      )
    }
  }
  